package com.demo.rocketmq.listener;

import com.alibaba.cloud.nacos.discovery.NacosServiceDiscovery;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.exception.NacosException;
import com.demo.rocketmq.constants.RocketMqConstants;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 通过获取nacos服务列表，划分服务分片值
 * @author cyj
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = RocketMqConstants.CALLBACK_PROPERTIES, name = "enable", havingValue = "true")
public class ServiceSharding {

    /**
     * 服务分片
     */
    private int shardingValue;
    /**
     * 记录该服务下机器总数
     */
    private int services;

    @Value("${spring.application.name}")
    private String applicationName;
    @Value("${server.port:8080}")
    private int serverPort;

    @Resource
    private NacosServiceDiscovery nacosServiceDiscovery;

    @EventListener(classes = HeartbeatEvent.class)
    public void listenNacosServiceInstance() {
        try {
            List<ServiceInstance> instances = nacosServiceDiscovery.getInstances(applicationName);
            List<String> hosts = instances.stream()
                    .map(s -> s.getHost() + ":" + s.getPort())
                    .sorted()
                    .collect(Collectors.toList());

            InetAddress inetAddress = InetAddress.getLocalHost();
            String ip = inetAddress.getHostAddress();

            shardingValue = hosts.indexOf(ip + ":" + serverPort);
            services = instances.size();

            log.info("hosts:{},当前主机ip:{},端口：{},shardingValue:{},在nacos注册的机器总数：{}", JSON.toJSONString(hosts), ip,
                    serverPort, shardingValue, services);
        } catch (NacosException e) {
            log.error("监听nacos心跳异常", e);
        } catch (UnknownHostException e) {
            log.error("获取本机ip异常", e);
        }
    }

    public int getShardingValue() {
        return shardingValue;
    }

    public int getServices() {
        return services;
    }
}
